<template>
    <Popup @register="registerPopup">
        <template #content>
            <div class="popup-spread-table">
                <div class="optrows">
                    <a-button type="primary" @click="onAddBtn">
                        <template #icon><PlusOutlined /></template>添加选项
                    </a-button>
                </div>
                <a-table 
                    sticky 
                    :columns="columns"
                    :data-source="optionList"
                    v-model:expandedRowKeys="expandedRowKeys"
                    :defaultExpandAllRows="true"
                    :pagination="false"
                    :rowKey="(record: any) => record?.optId"
                    @expand="onExpand"
                >
                    <template #bodyCell="{ record, column }">
                        <template v-if="column?.dataIndex == 'label'">
                            <a-input v-model:value="record.label" style="width: 200px;" placeholder="请输入选项名" />
                        </template>
                        <template v-if="column?.dataIndex == 'value'">
                            <template v-if="ruleTypeRef == 'string'">
                                <a-input v-model:value="record.value" style="width: 100%;" placeholder="请输入选项值" />
                            </template>
                            <template v-else>
                                <a-input-number 
                                    v-model:value="record.value"
                                    :precision="0"
                                    :controls="false"
                                    style="width: 100%;"
                                    placeholder="请输入默认值"
                                />
                            </template>
                        </template>
                        <template v-if="column?.dataIndex == 'operation'">
                            <a-space>
                                <a-button type="primary" size="small" @click="onAddSubBtn(record)">
                                    <template #icon><plus-outlined /></template>
                                </a-button>
                                <a-button type="primary" danger size="small" @click="onDelCurBtn(record)">
                                    <template #icon><delete-outlined /></template>
                                </a-button>
                            </a-space>
                        </template>
                    </template>
                </a-table>
            </div>
        </template>
    </Popup>
</template>

<script setup lang='ts'>
import { Popup, usePopup } from '@/components/popup/index';
import { deepClone, toChineseNumber } from '@/utils';
import { Modal } from 'ant-design-vue';

const emit = defineEmits(['update']);

const ruleTypeRef = ref<string>('');
const optionList = ref<Recordable[]>([]);
const optionCopyList = ref<Recordable[]>([]);
const expandedRowKeys = ref<string[]>([]);

const columns: Recordable[] = [
    { title: '选项名称', dataIndex: 'label', align: 'left', width: 250 },
    { title: '选项值', dataIndex: 'value', align: 'center', width: 250 },
    { title: '操作', dataIndex: 'operation', fixed: 'right', width: 86 },
];

// 弹出层属性配置
const [registerPopup, { openPopup, closePopup }] = usePopup({
    type: 'Drawer', // 弹出层类型
    title: '设置树选择项',
    styleType: 'spread',
    maskClosable: false,
    width: 750,
    confrimButton: async() => {
        if(!unref(optionList).length){
            Modal.error({ title: '至少要添加一项选择项进行保存' });
            return;
        }
        const isEmpty = isTreeEmpty(unref(optionList));
        if(!isEmpty){
            Modal.error({ title: '添加的选择项中存在“选项名称”或“选项值”未填写的数据，请填写完整数据！' });
            return;
        }
        emit('update', unref(optionList));
        setTimeout(() => {
            closePopup();
            Modal.success({ title: '保存选项成功！' });
        }, 500);
    },
});

const onExpand = (expanded: boolean, record: Recordable) => {
    const key = record.optId;
    if (expanded) {
        expandedRowKeys.value.push(key);
    } else {
        expandedRowKeys.value = expandedRowKeys.value.filter(k => k !== key);
    }
};

// 递归添加optId
const recurrence = (record: Recordable) => {
    record.optId = 'opt-'+Math.floor(Math.random() * 100000);
    if(record?.children && record?.children.length > 0){
        record.children.forEach((item:any) => {
            item.parentId = record?.optId;
            recurrence(item);
        });
        expandedRowKeys.value.push(record.optId);
    }
    return record;
};

// 判断两个树形数组对象键值是否一致
const isTreeEqual = (tree1: Recordable[], tree2: Recordable[]) => {
    if(tree1.length != tree2.length){
        return false;
    }

    for(let i = 0; i < tree1.length; i++){
        const item1 = tree1[i];
        const item2 = tree2[i];
        const arr1 = Object.values(item1);
        const arr2 = Object.values(item2);
        const isCompare = JSON.stringify(arr1) === JSON.stringify(arr2);
        if(isCompare == false){
            return false;
        }
        // 检查子节点
        const children1 = item1.children || [];
        const children2 = item2.children || [];
        if(children1.length && children2.length){
            if (children1.length !== children2.length) {
                return false;
            }else{
                isTreeEqual(children1, children2);
            }
        }else{
            return false;
        }
    }

    return true;
};

const onAddBtn = () => {
    const newParam = {
        optId: 'opt-'+Math.floor(Math.random() * 100000),
        label: '选项'+toChineseNumber((unref(optionList).length + 1)),
        value: Math.floor(Math.random() * 100000), // 自动生成value值
    };
    expandedRowKeys.value.push(newParam.optId);
    optionList.value.push(newParam);
};

// 新增子项按钮事件
const onAddSubBtn = (record: Recordable) => {
    if(!record?.children){
        record.children = [];
    }
    const newParam = {
        parentId: record?.optId,
        optId: 'opt-'+Math.floor(Math.random() * 100000),
        label: record.label+'-'+(record.children.length + 1),
        value: Math.floor(Math.random() * 100000), // 自动生成value值
    };
    expandedRowKeys.value.push(record.optId);
    record.children.push(newParam);
};

// 递归删除数据
const delRecurrence = (source: Recordable, target: Recordable) => {
    if(source?.children && source.children.length > 0){
        const spIdx = source.children.findIndex((item: Recordable) => item?.optId == target?.optId);
        if(spIdx != -1){
            source?.children.splice(spIdx, 1);
            if(source?.children.length == 0){
                delete source.children;
            }
        }else{
            source?.children.forEach((item: Recordable) => {
                delRecurrence(item, target);
            });
        }
    }
};
// 删除选项事件
const onDelCurBtn = (record: Recordable) => {
    const spIdx = unref(optionList).findIndex((item: Recordable) => item?.optId == record?.optId);
    if(spIdx != -1){
        optionList.value.splice(spIdx, 1);
    }else{
        optionList.value.forEach((item: Recordable) => {
            delRecurrence(item, record);
        });
    }
    const expIdx = unref(expandedRowKeys).findIndex((key:string) => key == record?.optId);
    if(expIdx != -1){
        expandedRowKeys.value.splice(expIdx, 1);
    }
};

// 判断树形数组对象键值是否为空
const isTreeEmpty = (tree: Recordable[]) => {
    for(let i = 0; i < tree.length; i++){
        const item = tree[i];
        if(!item?.value || !item?.label){
            return false;
        }
        if(item?.children && item?.children.length){
            return isTreeEmpty(item?.children);
        }
    }
    return true;
};

const close = async() => {
    const isExt = isTreeEqual(unref(optionList), unref(optionCopyList));
    if(!isExt){
        Modal.confirm({
            title: '当前设置的选项未进行保存，你确定要关闭窗口吗？',
            cancelText: '取消',
            onOk: () => closePopup(),
        });
        return;
    }
    await closePopup();
};

// 打开弹出层事件
const open = async (dataSoucre: Recordable[], ruleType: string) => {
    ruleTypeRef.value = ruleType;
    const options = deepClone(dataSoucre) as Recordable[];
    expandedRowKeys.value = [];
    optionList.value = [];
    optionList.value = options.map((item:any) => {
        item = recurrence(item);
        return item;
    });
    optionCopyList.value = deepClone(unref(optionList)) as Recordable[];

    await openPopup();
};

defineExpose({ close, open });
</script>

<style lang="less" scoped>
.optrows { background-color: #fff; padding: 12px 10px; }
</style>